Bun Jest Migration Bun's test runner is Jest-compatible. Most Jest tests run without changes. Quick Migration
1. Remove Jest dependencies
bun remove jest ts-jest @types/jest babel-jest
2. Update test script
package.json: "test": "bun test"
3. Run tests
bun
test
Import Changes
// Before (Jest)
import
{
describe
,
it
,
expect
,
jest
}
from
'@jest/globals'
;
// After (Bun) - No import needed, or explicit:
import
{
describe
,
test
,
expect
,
mock
,
spyOn
}
from
"bun:test"
;
API Compatibility
Fully Compatible
Jest
Bun
Notes
describe()
describe()
Identical
it()
/
test()
test()
Use
test()
expect()
expect()
Same matchers
beforeAll/Each
beforeAll/Each
Identical
afterAll/Each
afterAll/Each
Identical
jest.fn()
mock()
Use
mock()
jest.spyOn()
spyOn()
Identical
Requires Changes
Jest
Bun Equivalent
jest.mock('module')
mock.module('module', () => {...})
jest.useFakeTimers()
import { setSystemTime } from "bun:test"
jest.setTimeout()
Third argument to
test()
jest.clearAllMocks()
Call
.mockClear()
on each mock
Mock Migration
Mock Functions
// Jest
const
fn
=
jest
.
fn
(
)
.
mockReturnValue
(
'value'
)
;
// Bun
const
fn
=
mock
(
(
)
=>
'value'
)
;
// Or for compatibility:
import
{
jest
}
from
"bun:test"
;
const
fn
=
jest
.
fn
(
(
)
=>
'value'
)
;
Module Mocking
// Jest (top-level hoisting)
jest
.
mock
(
'./utils'
,
(
)
=>
(
{
helper
:
jest
.
fn
(
(
)
=>
'mocked'
)
}
)
)
;
// Bun (inline, no hoisting)
import
{
mock
}
from
"bun:test"
;
mock
.
module
(
'./utils'
,
(
)
=>
(
{
helper
:
mock
(
(
)
=>
'mocked'
)
}
)
)
;
Spy Migration
// Jest
jest
.
spyOn
(
console
,
'log'
)
.
mockImplementation
(
(
)
=>
{
}
)
;
// Bun (identical)
spyOn
(
console
,
'log'
)
.
mockImplementation
(
(
)
=>
{
}
)
;
Timer Migration
// Jest
jest
.
useFakeTimers
(
)
;
jest
.
setSystemTime
(
new
Date
(
'2024-01-01'
)
)
;
jest
.
advanceTimersByTime
(
1000
)
;
// Bun - supports Jest-compatible timer APIs
import
{
setSystemTime
}
from
"bun:test"
;
import
{
jest
}
from
"bun:test"
;
jest
.
useFakeTimers
(
)
;
jest
.
setSystemTime
(
new
Date
(
'2024-01-01'
)
)
;
jest
.
advanceTimersByTime
(
1000
)
;
// Now supported
Snapshot Testing
// Jest
expect
(
component
)
.
toMatchSnapshot
(
)
;
expect
(
data
)
.
toMatchInlineSnapshot
(
"expected"
)
;
// Bun (identical)
expect
(
component
)
.
toMatchSnapshot
(
)
;
expect
(
data
)
.
toMatchInlineSnapshot
(
"expected"
)
;
Update snapshots:
bun
test
--update-snapshots
Configuration Migration
jest.config.js → bunfig.toml
// jest.config.js (before)
module
.
exports
=
{
testMatch
:
[
'*/.test.ts'
]
,
testTimeout
:
10000
,
setupFilesAfterEnv
:
[
'./jest.setup.ts'
]
,
collectCoverage
:
true
,
coverageThreshold
:
{
global
:
{
lines
:
80
}
}
}
;
bunfig.toml (after)
[ test ] root = "./" preload = [ "./jest.setup.ts" ] timeout = 10000 coverage = true coverageThreshold = 0.8 Common Migration Issues Issue: jest.mock Not Working // Jest mock hoisting doesn't exist in Bun // Move mock.module before imports or use dynamic imports // Solution 1: Use mock.module at top mock . module ( './api' , ( ) => ( { fetch : mock ( ) } ) ) ; import { fetch } from './api' ; // Solution 2: Dynamic import const mockFetch = mock ( ) ; mock . module ( './api' , ( ) => ( { fetch : mockFetch } ) ) ; const { fetch } = await import ( './api' ) ; Issue: Timer Functions Missing // Bun timer support is limited // Use setSystemTime for date mocking import { setSystemTime } from "bun:test" ; beforeEach ( ( ) => { setSystemTime ( new Date ( '2024-01-01' ) ) ; } ) ; afterEach ( ( ) => { setSystemTime ( ) ; // Reset to real time } ) ; Issue: Custom Matchers // Jest expect . extend ( { toBeWithinRange ( received , floor , ceiling ) { ... } } ) ; // Bun (same API) import { expect } from "bun:test" ; expect . extend ( { toBeWithinRange ( received , floor , ceiling ) { const pass = received
= floor && received <= ceiling ; return { pass , message : ( ) =>
expected ${ received } to be within ${ floor } - ${ ceiling }} ; } } ) ; Step-by-Step Migration Remove Jest packages bun remove jest ts-jest @types/jest babel-jest jest-environment-jsdom Update package.json { "scripts" : { "test" : "bun test" , "test:watch" : "bun test --watch" , "test:coverage" : "bun test --coverage" } } Convert jest.config.js to bunfig.toml Update imports in test files Find/replace @jest/globals → bun:test Find/replace jest.fn() → mock() Find/replace jest.mock() → mock.module() Run and fix bun test 2&1 | head -50
Check first errors
Common Errors Error Cause Fix Cannot find module '@jest/globals' Old import Use bun:test jest is not defined Global jest Import from bun:test mock.module is not a function Wrong import import { mock } from "bun:test" Snapshot mismatch Different serialization Update with --update-snapshots When to Load References Load references/compatibility-matrix.md when: Full Jest API compatibility details Unsupported features list Workarounds for missing features